﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vds2465Telegrams;

namespace Vds2465Parser
{
    internal static class GenParse_UserData_11_Error
    {
        #region private constants

        private const int NrOfBytes = 4;

        private const int NrOfBytes_UnknownUserDataType = 5;
        private const byte UnknownUserDataTypeByte = 0xFF;

        #endregion private constants

        internal static byte[] GenerateBytes(UserData userData)
        {
            byte[] userDataBytes = null;

            if (userData is UserData_11_Error)
            {
                UserData_11_Error userData11 = userData as UserData_11_Error;
                userDataBytes = new byte[NrOfBytes];
                userDataBytes[0] = NrOfBytes - GenParse_UserData.HeaderLength;	// user data length
                userDataBytes[1] = UserData.UserData11Error;
                userDataBytes[2] = userData11.Device;
                userDataBytes[3] = GenParse_ErrorCode.GenerateByte(userData11.ErrorCode);
            }
            else if (userData is UserData_11_Error_UserDataTypeUnknown)
            {
                UserData_11_Error_UserDataTypeUnknown userData11 = userData as UserData_11_Error_UserDataTypeUnknown;
                userDataBytes = new byte[NrOfBytes_UnknownUserDataType];
                userDataBytes[0] = NrOfBytes_UnknownUserDataType - GenParse_UserData.HeaderLength;	// user data length
                userDataBytes[1] = UserData.UserData11Error;
                userDataBytes[2] = userData11.Device;
                userDataBytes[3] = UnknownUserDataTypeByte;
                userDataBytes[4] = userData11.UnknownUserDataType;
            }
            else
            {
                // TODO handle error
            }

            return userDataBytes;
        }

        internal static bool ParseBytes(byte[] userDataBytes, out UserData userData11, out int consumedBytes)
        {
            userData11 = null;
            consumedBytes = 0;

            if (userDataBytes.Length >= NrOfBytes)
            {
                // first byte
                if (
                    (userDataBytes[0] == NrOfBytes - GenParse_UserData.HeaderLength)
                    || (userDataBytes[0] == NrOfBytes_UnknownUserDataType - GenParse_UserData.HeaderLength)
                    )
                {
                    if (userDataBytes[1] == UserData.UserData11Error)
                    {
                        byte device = userDataBytes[2];
                        byte errorCodeByte = userDataBytes[3];
                        eErrorCode errorCode;
                        bool bRetVal = GenParse_ErrorCode.ParseByte(errorCodeByte, out errorCode);
                        if (bRetVal)
                        {
                            // we need to check the length again
                            if (userDataBytes[0] == NrOfBytes - GenParse_UserData.HeaderLength)
                            {
                                userData11 = new UserData_11_Error(errorCode, device);
                                consumedBytes = NrOfBytes;
                                return true;
                            }

                            // TODO handle error (wrong value in first byte the length)
                            return false;
                        }
                        else if (errorCodeByte == UnknownUserDataTypeByte)
                        {
                             // we need to check the length again
                            if (userDataBytes[0] == NrOfBytes_UnknownUserDataType - GenParse_UserData.HeaderLength)
                            {
                                if (userDataBytes.Length >= NrOfBytes_UnknownUserDataType)
                                {
                                    userData11 = new UserData_11_Error_UserDataTypeUnknown(device, userDataBytes[4]);
                                    consumedBytes = NrOfBytes_UnknownUserDataType;
                                    return true;
                                }

                                // TODO handle error (not enough bytes  for specific error code)
                                return false;
                            }

                            // TODO handle error (wrong value in first byte the length)
                            return false;
                        }

                        // TODO handle error - wrong value for the ErrorCode
                        return false;
                    }

                    // TODO handle error - wrong value for the data type
                    return false;
                }

                // TODO handle error (wrong value in first byte the length)
                return false;
            }

            // TODO handle error (not enough bytes)
            return false;
        }
    }
}
